package apps.sim.core;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import apps.sim.action.handler.HandlerFactory;
import apps.sim.core.Trapping.Contexthandler;

import com.sun.net.httpserver.HttpServer;

public class Trapper {
	private static final Map<Trapping, HttpServer> servers = new HashMap<Trapping, HttpServer>();

	public static void startAndAddContext(String url, String clazz) throws Exception {
		Trapping trapping = new Trapping(url);
		final IHandler handler = HandlerFactory.getInstance().getHandler(clazz);
		final InetSocketAddress addr = new InetSocketAddress(trapping.getHost(), trapping.getPort());
		final HttpServer httpServer = servers.get(trapping);
		if (httpServer == null) {
			trapping.setHandler(handler);
			HttpServer server = HttpServer.create(addr, 0);
			server.setExecutor(ExecutorFactory.arrayBlockingExecutor());			
			server.start();
			servers.put(trapping, server);
		} else {
			trapping = findActual(servers.keySet(), trapping);
			trapping.setHandler(handler);
		}

		final Set<Contexthandler> contexts = trapping.getContexts();
		for (Contexthandler context : contexts) {
			final String contextPath = context.getContext();
			servers.get(trapping).createContext(contextPath, new HttpRequestHandler(contextPath, context.getHandler()));
		}

	}

	private static Trapping findActual(Set<Trapping> keySet, Trapping trapping) {
		for (Trapping key : keySet) {
			if (key.equals(trapping)) {
				return key;
			}
		}
		return trapping;
	}

	public static void removeContext(String url, String clazz) throws Exception {
		final Trapping trapping = new Trapping(url);
		final IHandler handler = HandlerFactory.getInstance().getHandler(clazz);
		trapping.setHandler(handler);
		final Set<Contexthandler> contexts = trapping.getContexts();
		for (Contexthandler context : contexts) {
			final HttpServer httpServer = servers.get(trapping);
			if (httpServer != null) {
				try {
					httpServer.removeContext(context.getContext());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void stop() {
		final Set<Entry<Trapping, HttpServer>> entrySet = servers.entrySet();
		for (Entry<Trapping, HttpServer> entry : entrySet) {
			entry.getValue().stop(1);
		}
	}
}
